import { app, shell, BrowserWindow, ipcMain, protocol, net, globalShortcut } from 'electron'
import { electronApp, optimizer } from '@electron-toolkit/utils'
import { main } from './browsers/index';
import commonConst from "@shared/utils/platform"

import createTray from './common/tray';
import localConfig from "./common/localConfig"
import { InitI18n } from "./common/i18nConfig"
import sysAPI from './core/sysAPI';
import localrpcServer from "./core/rpcServer"

const i18next = require('i18next');
const path = require('node:path');
const { pathToFileURL } = require('url')


// Register a protocol
// https://www.electronjs.org/zh/docs/latest/api/protocol
protocol.registerSchemesAsPrivileged([
  { scheme: 'app', 
    privileges: { secure: true, standard: true, bypassCSP: true } },
]);


class App {

  public windowCreator: { init: () => void; 
    getWindow: () => BrowserWindow; 
    getIsQuitting: () => boolean; 
    setQuitting: (status: boolean) => void
  };
  // private systemPlugins: any;

  constructor() {
    protocol.handle('app', (request) => {
      const {host, pathname } = new URL(request.url)

      if (host === 'bundle') {
      // NB, this checks for paths that escape the bundle, e.g.
      // app://bundle/../../secret_file.txt
      const pathToServe = path.resolve(__dirname, ".." + pathname.toString())
      return net.fetch(pathToFileURL(pathToServe).toString())
      } else {
        return new Response('bad', {
          status: 400,
          headers: { 'content-type': 'text/html' }
        })
      }
    })
    this.windowCreator = main();
    const gotTheLock = app.requestSingleInstanceLock();

    if (!gotTheLock) {
      app.quit()
    } else {
      this.beforeReady()
      this.onReady()
      this.onRunning()
      this.onQuit()
    }
  }

  LodingDone() {
    console.log("loading done")
  }

  createWindow() {
    this.windowCreator.init();
  }

  beforeReady() {
    if (commonConst.macOS()) {
      
    }
  }

  onReady() {
    const readyFunction = async () => {
      electronApp.setAppUserModelId('com.lazisoft')
      console.log(i18next.t("welcome"))

      // Default open or close DevTools by F12 in development
      // and ignore CommandOrControl + R in production.
      // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
      app.on('browser-window-created', (_, window) => {
        optimizer.watchWindowShortcuts(window)
      })
      // IPC test
      ipcMain.on('ping', () => console.log('pong'))

      this.createWindow();
      const mainWindow = this.windowCreator.getWindow();
      if (commonConst.dev()){
        mainWindow.webContents.openDevTools()
      }
      createTray(mainWindow, this.windowCreator.setQuitting)

      mainWindow.webContents.setWindowOpenHandler((details) => {
        shell.openExternal(details.url)
        return { action: 'deny' }
      })
    }

    if (!app.isReady()) {
      app.on('ready', readyFunction);
    } else {
      readyFunction();
    }
  }

  onRunning() {
    app.on('second-instance', () => {
      // const files = getSearchFiles(commandLine, workingDirectory);
      // Someone tried to run a second instance, we should focus our window.
      const win = this.windowCreator.getWindow();
      if (win) {
        if (win.isMinimized()) {
          win.restore()
        }
        win.focus()
      }
    })

    app.on("activate", () => {
      const win = this.windowCreator.getWindow();
      if (!win) {
        this.createWindow();
      }
    });

    if (commonConst.windows()) {
      // app.setAppUserModelId("pkg.build.appId")
    }


  }

  onQuit() {
    // Quit when all windows are closed, except on macOS. There, it's common
    // for applications and their menu bar to stay active until the user quits
    // explicitly with Cmd + Q.

    app.on('window-all-closed', () => {
      if (process.platform !== 'darwin') {
        app.quit();
      }
    })

    app.on('will-quit', () => {
      globalShortcut.unregisterAll();
    });

    if (commonConst.dev()) {
      if (process.platform === 'win32') {
        process.on('message', (data) => {
          if (data === 'graceful-exit') {
            app.quit();
          }
        });
      } else {
        process.on('SIGTERM', () => {
          app.quit();
        });
      }
    }
  }

}

app.on('ready', () => {
  let current_lang = "zh-CN"
  let local_config = localConfig.getConfig()
  console.log(Object.keys(local_config))
  if (Object.keys(local_config).length !== 0) {
    current_lang = local_config["lang"]
  } else {
    current_lang = app.getLocale()
    console.log(current_lang)
  }

  sysAPI.init()

  InitI18n(current_lang).then(() => {
    const appInstance = new App();
    appInstance.LodingDone();
    app.commandLine.appendSwitch('lang', 'en-US');
    app.commandLine.appendSwitch('lang', 'zh-CN');
  })

  localrpcServer.listen(6310, () => {
    console.log('Local RPC server listening on port 6310');
})
});
